package com.lanchetech.admin.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.admin.service.LotteryService;
import com.lanchetech.bean.dto.LotterySettingDTO;
import com.lanchetech.bean.request.LotteryOrderReq;
import com.lanchetech.bean.request.LotterySpuListReq;
import com.lanchetech.bean.request.PageReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.LotteryOrderResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.LotteryRecordVO;
import com.lanchetech.common.enums.CoinProductTypeEnum;
import com.lanchetech.common.enums.DeletedEnum;
import com.lanchetech.common.enums.PrizeTypeEnum;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.dao.LotteryMapper;
import com.lanchetech.dao.LotteryOrderMapper;
import com.lanchetech.dao.LotteryRecordMapper;
import com.lanchetech.dao.SpuMapper;
import com.lanchetech.entity.Lottery;
import com.lanchetech.entity.LotteryRecord;
import com.lanchetech.entity.Spu;
import com.lanchetech.entity.User;
import com.lanchetech.service.DaoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LotteryServiceImpl implements LotteryService {

    @Autowired
    LotteryMapper lotteryMapper;

    @Autowired
    LotteryRecordMapper lotteryRecordMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private LotteryOrderMapper lotteryOrderMapper;

    @Override
    public BaseResp editLottery(Lottery req) {

        if(StringUtils.isEmpty(req.getSetting())){
            return new BaseResp(ResultCode.FAIL);
        }

        List<LotterySettingDTO> settingList = JSON.parseArray(req.getSetting(), LotterySettingDTO.class);

        if(CollectionUtils.isEmpty(settingList)){
            return new BaseResp(ResultCode.FAIL);
        }

        boolean hasThank = false;
        for (LotterySettingDTO item : settingList) {
            if(PrizeTypeEnum.THANK.getType().equals(item.getPrizeType())){
                hasThank = true;
            }
            // 如果奖品为常规商品 则必须有prizeId
            if(PrizeTypeEnum.POINTS.getType().equals(item.getPrizeType()) && Objects.isNull(item.getPrizeId())){
                return new BaseResp(ResultCode.LOTTERY_MUST_PRIZE_ID);
            }
            if (StringUtils.isEmpty(item.getPrizeImage())){
                return new BaseResp(ResultCode.LOTTERY_MUST_PRIZE_IMAGE);
            }
        }

        if(!hasThank){
            return new BaseResp(ResultCode.LOTTERY_MUST_HAS_THANK);
        }

        if((CoinProductTypeEnum.NINE_LOTTERY.getType().equals(req.getType()) || CoinProductTypeEnum.TURNTABLE_LOTTERY.getType().equals(req.getType())) && settingList.size() != 8){
            return new BaseResp(ResultCode.MUST_BE_EIGHT_PRIZE);
        }

        // 计算总概率
        BigDecimal totalProbability = settingList.stream().map(item -> item.getProbability()).reduce(BigDecimal.ZERO, BigDecimal::add);
        if(new BigDecimal(100).compareTo(totalProbability) != 0){
            return new BaseResp(ResultCode.LOTTERY_PROBABILITY_MUST_BE_100);
        }

        // 先判断
        if(req.getId() == null) {
            req.setJoinCount(0);
            req.setDeleted(DeletedEnum.DEFAULT.getStatus());
            req.setCreatedAt(new Date());
            req.setUpdatedAt(new Date());
            lotteryMapper.insert(req);
        }else{
            req.setUpdatedAt(new Date());
            lotteryMapper.updateByPrimaryKeySelective(req);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Lottery>> getLotteryPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Lottery> list = lotteryMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp deleteLottery(Long id) {
        lotteryMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
        return new BaseResp();
    }

    @Override
    public ResultData<Lottery> getLotteryDetail(Long id) {
        return new ResultData<>(lotteryMapper.selectByPrimaryKey(id));
    }

    @Override
    public ResultData<BasePageResp<LotteryRecordVO>> getLotteryRecordPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<LotteryRecord> list = lotteryRecordMapper.findAllPage(req);
        List<LotteryRecordVO> result = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            Map<Long, User> map = daoService.getUserMap(list.stream().map(LotteryRecord::getUserId).collect(Collectors.toList()));
            list.stream().forEach(item->{
                LotteryRecordVO vo = new LotteryRecordVO();
                BeanUtils.copyProperties(item, vo);
                vo.setAvatar(map.get(item.getUserId()).getAvatar());
                vo.setNickname(map.get(item.getUserId()).getNickname());
                vo.setUsername(map.get(item.getUserId()).getUsername());
                result.add(vo);
            });
        }
        return PageHelpUtil.buildPage(result, page);
    }

    @Override
    public ResultData lotterySpuList(LotterySpuListReq lotterySpuListReq) {
        Page page = PageHelper.startPage(lotterySpuListReq.getPageNo(), lotterySpuListReq.getPageSize());
        List<Spu> spuList = spuMapper.lotterySpuList(lotterySpuListReq);
        return PageHelpUtil.buildPage(spuList, page);
    }

    @Override
    public ResultData lotteryOrder(LotteryOrderReq lotteryOrderReq) {
        Page page = PageHelper.startPage(lotteryOrderReq.getPageNo(), lotteryOrderReq.getPageSize());
        List<LotteryOrderResp> lotteryOrderResp = lotteryOrderMapper.queryLotteryOrder(lotteryOrderReq);
        return PageHelpUtil.buildPage(lotteryOrderResp, page);
    }

    @Override
    public ResultData<LotteryOrderResp> getLotteryOrderDetail(Long id) {
        LotteryOrderReq req = new LotteryOrderReq();
        req.setId(id);
        List<LotteryOrderResp> lotteryOrderResps = lotteryOrderMapper.queryLotteryOrder(req);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(lotteryOrderResps)) {
            return new ResultData<>(lotteryOrderResps.get(0));
        }
        return null;
    }
}